// Package frontdesk
// @program: beegoblog02
// @author: Hyy
// @create: 2022-05-06 23:20
package frontdesk

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/context"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
	"individual/models"
	"individual/utils"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"time"
)

// FilterUser
// 过滤中间件,验证用户是否已经登录
func FilterUser(c *context.Context) {
	token := c.Input.Header("auth")
	if token == "" {
		c.Redirect(302, "/login")
	}
	tokenMap, err := utils.ValidateToken(token)
	if err != nil {
		logs.Info("解析token，失败，err:", err.Error())
		return
	}
	o := orm.NewOrm()
	var user models.User
	o.QueryTable(new(models.User).TableName()).One(&user)
	if user.AuthUsername != tokenMap["userName"].(string) {
		c.ResponseWriter.Write([]byte("非博客所有者，禁止進入後台"))
	}
}

func Login(c *context.Context) {
	o := orm.NewOrm()
	host := c.Request.Host
	clientId := host[:len(host)-1] + "0" // 前端 8080 接口
	//clientId := c.Request.Host
	var user models.User
	o.QueryTable(new(models.User).TableName()).Filter("client_id", clientId).One(&user)
	if user.ClientId == "" {
		_, err := o.Insert(&models.User{
			CreatAt:  time.Now(),
			ClientId: clientId,
			Theme:    "default",
			Nickname: "default",
		})
		if err != nil {
			logs.Info("auth2，ClientId 插入失败 err:", err)
			return
		}
		clientSecret := clientId
		redirectUri := fmt.Sprintf("http://%v/admin/adminHome", clientId)
		//redirectUri := fmt.Sprintf("http://%v/getTokenByCode", clientId)
		tokenUrl := "https://oauth.bannerstudio.club/user/oauthClientDetails"
		data := url.Values{
			"clientId":              []string{clientId},
			"resourceIds":           []string{beego.AppConfig.String("RESOURCE_IDS")},
			"clientSecret":          []string{clientSecret},
			"scope":                 []string{"all"},
			"authorizedGrantTypes":  []string{beego.AppConfig.String("AUTHORIZED_GRANT_TYPES")},
			"webServerRedirectUri":  []string{redirectUri},
			"authorities":           nil,
			"accessTokenValidity":   []string{beego.AppConfig.String("ACCESS_TOKEN_VALIDITY")},
			"refreshTokenValidity":  []string{beego.AppConfig.String("REFRESH_TOKEN_VALIDITY")},
			"additionallnformation": nil,
			"autoapprove":           nil,
		}
		_, err = http.PostForm(tokenUrl, data)
		if err != nil {
			logs.Info(err)
			return
		}
	}
	toAuth := fmt.Sprintf("https://oauth.bannerstudio.club/oauth/authorize?"+
		"client_id=%s"+
		"&response_type=%s"+
		"&scope=%s"+
		"&redirect_uri=%s",
		clientId,
		beego.AppConfig.String("RESPONSE_TYPE"),
		beego.AppConfig.String("SCOPE"),
		// admin/adminHome
		fmt.Sprintf("http://%v/admin/adminHome", clientId))
	//fmt.Sprintf("http://%v/getTokenByCode", clientId))
	//c.Redirect(http.StatusTemporaryRedirect,toAuth)
	r := make(map[string]interface{})
	r["url"] = toAuth
	c.Output.JSON(r, true, true)
}

func GetTokenByCode(c *context.Context) {
	o := orm.NewOrm()
	host := c.Request.Host
	clientId := host[:len(host)-1] + "0"
	//clientId := c.Request.Host
	code := c.Input.Query("code")
	tokenUrl := "https://oauth.bannerstudio.club/oauth/token"
	data := url.Values{
		"code":          []string{code},
		"client_id":     []string{clientId},
		"client_secret": []string{clientId},
		"redirect_uri":  []string{fmt.Sprintf("http://%v/admin/adminHome", clientId)},
		//"redirect_uri":  []string{fmt.Sprintf("http://%v/getTokenByCode", clientId)},
		"grant_type": []string{beego.AppConfig.String("GRANT_TYPE")},
	}
	resp, err := http.PostForm(tokenUrl, data)
	if err != nil {
		log.Println(err)
		return
	}
	defer resp.Body.Close()

	bodyContent, err := ioutil.ReadAll(resp.Body)
	respMap := make(map[string]interface{})
	err = json.Unmarshal(bodyContent, &respMap)
	if err != nil {
		log.Println("获取失败", err)
		return
	}
	token := respMap["access_token"].(string)
	// 每次拿取token,之後解析token去看一下，auth表里有没有管理员存在，如果有的话，这个就是
	tokenMap, err := utils.ValidateToken(token)
	if err != nil {
		logs.Info("解析token，失败，err:", err.Error())
		return
	}
	user := models.User{}
	o.QueryTable(new(models.User).TableName()).One(&user)
	if user.ClientId != "" && user.AuthUsername == "" {
		// 如果是第一次登录，初始化管理员信息
		client := http.Client{}
		req, err01 := http.NewRequest(http.MethodGet,
			fmt.Sprintf("https://oauth.bannerstudio.club/admin/getInformation/%s", tokenMap["userName"]),
			nil)
		if err01 != nil {
			logs.Info("创建新的请求出错,err: ", err01)
			return
		}
		req.Header.Add("Authorization", "Bearer "+token)
		resp, err01 = client.Do(req)
		if err01 != nil {
			logs.Info("申请授權中心用户信息失败,err: ", err01)
			return
		}
		defer resp.Body.Close()
		bodyContent02, _ := ioutil.ReadAll(resp.Body)
		respMap02 := make(map[string]interface{})
		if err02 := json.Unmarshal(bodyContent02, &respMap02); err02 != nil {
			logs.Info("解析失敗，獲取授權中用戶信息失敗,err: ", err)
			return
		}
		user.AuthUsername = respMap02["userName"].(string)
		user.Email = respMap02["email"].(string)
		user.HeadPortrait = respMap02["headPortraitUrl"].(string)
		o.Update(&user)
	}
	c.Output.JSON(map[string]interface{}{
		"token": token,
	}, true, true)
}
